package com.ehotting.edsta.circuitDesign.service.impl;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;

public abstract class ExcelToMapListListThreadPool<T> {
    // 设置核心线程数
    private int corePoolSize = 12;
    // 最大线程数
    private int maximumPoolSize = 12;
    // 最大空闲时间
    private int keepAliveTime = 2;
    // 队列大小
    private int workQueue = 13;
    // 拒绝策略
    //（1）ThreadPoolExecutor.AbortPolicy 丢弃任务，并抛出 RejectedExecutionException 异常。
    //（2）ThreadPoolExecutor.CallerRunsPolicy：该任务被线程池拒绝，由调用 execute方法的线程执行该任务。
    //（3）ThreadPoolExecutor.DiscardOldestPolicy ： 抛弃队列最前面的任务，然后重新尝试执行任务。
    //（4）ThreadPoolExecutor.DiscardPolicy，丢弃任务，不过也不抛出异常。
    //也可以自己实现RejectedExecutionHandler接口来自定义拒绝策略
    // 线程名前缀
    private String threadNamePrefix = "excelToMapListListThreadPool-";

    public void execute(List<T> list){

        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(corePoolSize);
        taskExecutor.setMaxPoolSize(maximumPoolSize+list.size());
        taskExecutor.setKeepAliveSeconds(keepAliveTime);
        taskExecutor.setQueueCapacity(workQueue+list.size());
        taskExecutor.setThreadNamePrefix(threadNamePrefix);
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        taskExecutor.initialize();

        //计数器，判断线程是否执行结束
        CountDownLatch taskLatch = new CountDownLatch(list.size());
        for(T t : list){
            taskExecutor.execute(() -> {
                task(t);
                taskLatch.countDown();
//                System.out.println(taskLatch.getCount());
            });
        }


        try {
            //当前线程阻塞，等待计数器置为0
            taskLatch.await();
        }catch (Exception e){
            e.printStackTrace();
        }
        taskExecutor.shutdown();
    }

    public abstract void task(T t);

}
